<!--
 * @Author: 梁青春
 * @Date: 2025-10-14 13:01:53
 * @LastEditTime: 2025-11-13 15:23:04
 * @LastEditors: 梁青春
-->
<template>
  <div class="patient-info">
    <h-form :column="3" :model="form" :rules="rules" :readonly="edit" ref="hFormRef">
      <readonly-form-item label="姓名" prop="name">
        <div class="grounp-box">
          <div class="grounp-box-name">
            <el-input v-model="form.name" />
          </div>
          <div class="grounp-box-gender">
            <el-select v-model="form.gender" placeholder="请选择性别">
              <el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value" />
            </el-select>
          </div>
        </div>
      </readonly-form-item>
      <readonly-form-item label="出生日期" prop="birthDate">
        <el-date-picker
          v-model="form.birthDate"
          type="date"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD"
          placeholder="请选择出生日期"
          :disabled-date="disabledDate"
          @change="calculateAge"
        />
      </readonly-form-item>
      <readonly-form-item label="年龄" prop="age">
        <el-input v-model="form.age" readonly />
      </readonly-form-item>
      <readonly-form-item label="出生地" prop="birthPlace">
        <!-- 替换为异步地区选择器组件，支持省市区多级联动 -->
        <AreaCascader v-model="form.birthPlace" />
      </readonly-form-item>
      <readonly-form-item label="籍贯" prop="nativePlace">
        <!-- 替换为异步地区选择器组件，支持省市区多级联动 -->
        <AreaCascader v-model="form.nativePlace" />
      </readonly-form-item>
      <readonly-form-item label="国籍" prop="nationality">
        <el-select v-model="form.nationality" placeholder="请选择国籍">
          <el-option v-for="dict in sys_user_nationality" :key="dict.value" :label="dict.label" :value="dict.value" />
        </el-select>
      </readonly-form-item>
      <readonly-form-item label="民族" prop="ethnicGroup">
        <el-select v-model="form.ethnicGroup" placeholder="请选择民族">
          <el-option v-for="dict in sys_user_ethnicity" :key="dict.value" :label="dict.label" :value="dict.value" />
        </el-select>
      </readonly-form-item>
      <readonly-form-item label="婚姻" prop="maritalStatus">
        <el-select v-model="form.maritalStatus" placeholder="请选择婚姻">
          <el-option
            v-for="dict in sys_user_marital_status"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </readonly-form-item>
      <el-form-item label="证件" prop="idType">
        <div class="grounp-box">
          <div class="grounp-box-idType">
            <el-select v-model="form.idType" placeholder="请选择证件类型" v-if="!edit">
              <el-option
                v-for="dict in sys_user_idcard_type"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
            <dict-tag :options="sys_user_idcard_type" :value="form.idType" v-else />
          </div>
          <div class="grounp-box-idNumber">
            <el-input v-model="form.idNumber" placeholder="请输入证件号码" :readonly="edit" />
          </div>
        </div>
      </el-form-item>
      <readonly-form-item label="手机号" prop="phoneNumber">
        <el-input v-model="form.phoneNumber" placeholder="请输入手机号" />
      </readonly-form-item>
      <readonly-form-item label="医保号" prop="medicalInsuranceNumber">
        <el-input v-model="form.medicalInsuranceNumber" placeholder="读卡后绑定" />
      </readonly-form-item>
      <readonly-form-item label="来源" prop="source">
        <el-select v-model="form.source" placeholder="请选择来源类型">
          <el-option v-for="dict in sys_user_source_type" :key="dict.value" :label="dict.label" :value="dict.value" />
        </el-select>
      </readonly-form-item>
      <readonly-form-item label="户口地址" prop="accountAddress">
        <!-- 替换为异步地区选择器组件，支持省市区多级联动 -->
        <AreaCascader v-model="form.accountAddress" />
      </readonly-form-item>
      <readonly-form-item label="详细地址" prop="detailAddress">
        <el-input v-model="form.detailAddress" placeholder="请输入详细地址" />
      </readonly-form-item>
      <readonly-form-item label="户口邮编" prop="householdPostalCode">
        <el-input v-model="form.householdPostalCode" placeholder="请输入户口邮编" />
      </readonly-form-item>
      <readonly-form-item label="家庭住址" prop="homeAddress">
        <!-- 替换为异步地区选择器组件，支持省市区多级联动 -->
        <AreaCascader v-model="form.homeAddress" />
      </readonly-form-item>
      <readonly-form-item label="详细地址" prop="homeDetailAddress">
        <el-input v-model="form.homeDetailAddress" placeholder="请输入详细地址" />
      </readonly-form-item>
      <readonly-form-item label="家庭邮编" prop="homePostalCode">
        <el-input v-model="form.homePostalCode" placeholder="请输入家庭邮编" />
      </readonly-form-item>
      <readonly-form-item label="家庭电话" prop="homePhone">
        <el-input v-model="form.homePhone" placeholder="请输入家庭电话" />
      </readonly-form-item>
      <readonly-form-item label="职业" prop="occupationType">
        <el-select v-model="form.occupationType" placeholder="请选择职业类型">
          <el-option
            v-for="dict in sys_user_occupation_type"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </readonly-form-item>
      <readonly-form-item label="单位" prop="company">
        <el-input v-model="form.company" placeholder="请输入单位" />
      </readonly-form-item>
      <readonly-form-item label="单位电话" prop="companyPhone">
        <el-input v-model="form.companyPhone" placeholder="请输入单位电话" />
      </readonly-form-item>
      <readonly-form-item label="单位地址" prop="companyAddress">
        <!-- 替换为异步地区选择器组件，支持省市区多级联动 -->
        <AreaCascader v-model="form.companyAddress" />
      </readonly-form-item>
      <readonly-form-item label="详细地址" prop="companyDetailAddress">
        <el-input v-model="form.companyDetailAddress" placeholder="请输入详细地址" />
      </readonly-form-item>
      <readonly-form-item label="单位邮编" prop="companyPostalCode">
        <el-input v-model="form.companyPostalCode" placeholder="请输入单位邮编" />
      </readonly-form-item>
      <readonly-form-item label="联系人" prop="contactPerson">
        <el-input v-model="form.contactPerson" placeholder="请输入联系人" />
      </readonly-form-item>
      <readonly-form-item label="联系人电话" prop="contactPhone">
        <el-input v-model="form.contactPhone" placeholder="请输入联系电话" maxlength="11" />
      </readonly-form-item>
      <readonly-form-item label="联系人关系" prop="contactRelationship">
        <el-select v-model="form.contactRelationship" placeholder="请选择联系人关系">
          <el-option
            v-for="dict in sys_user_contact_relation"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </readonly-form-item>
      <readonly-form-item label="联系人地址" prop="contactAddress">
        <!-- 替换为异步地区选择器组件，支持省市区多级联动 -->
        <AreaCascader v-model="form.contactAddress" />
      </readonly-form-item>
      <readonly-form-item label="详细地址" prop="contactDetailAddress">
        <el-input v-model="form.contactDetailAddress" placeholder="请输入详细地址" />
      </readonly-form-item>
      <readonly-form-item label="备注" prop="remark">
        <el-input v-model="form.remark" placeholder="请输入备注" />
      </readonly-form-item>
    </h-form>
  </div>
</template>
<script setup name="PatientInfo">
import HForm from '@/components/HForm/index.vue'
import AreaCascader from '@/components/AreaCascader.vue'
import { readonly } from 'vue'
const { proxy } = getCurrentInstance()
const {
  sys_user_sex,
  sys_user_nationality,
  sys_user_ethnicity,
  sys_user_marital_status,
  sys_user_idcard_type,
  sys_user_contact_relation,
  sys_user_source_type,
  sys_user_occupation_type
} = proxy.useDict(
  'sys_user_sex',
  'sys_user_nationality',
  'sys_user_ethnicity',
  'sys_user_marital_status',
  'sys_user_idcard_type',
  'sys_user_contact_relation',
  'sys_user_source_type',
  'sys_user_occupation_type'
)

const props = defineProps({
  edit: {
    type: Boolean,
    default: false
  },
  patient: {
    type: Object,
    default: () => ({})
  }
})
// 地区选择器改为异步加载，无需静态 options

const form = ref({
  name: null,
  gender: '0',
  birthDate: null,
  age: null,
  ethnicGroup: '01',
  nationality: 'cn',
  maritalStatus: '1',
  source: '1',
  occupationType: '1',
  idType: '1',
  idNumber: null,
  company: null,
  companyPhone: null,
  companyAddress: null,
  companyDetailAddress: null,
  companyPostalCode: null,
  contactName: null,
  contactPhone: null,
  contactRelationship: '1',
  contactAddress: null,
  contactDetailAddress: null,
  remark: null
})

const resetForm = () => {
  form.value = {
    name: null,
    gender: '0',
    birthDate: null,
    age: null,
    ethnicGroup: '01',
    nationality: 'cn',
    maritalStatus: '1',
    source: '1',
    occupationType: '1',
    idType: '1',
    idNumber: null,
    company: null,
    companyPhone: null,
    companyAddress: null,
    companyDetailAddress: null,
    companyPostalCode: null,
    contactName: null,
    contactPhone: null,
    contactRelationship: '1',
    contactAddress: null,
    contactDetailAddress: null,
    remark: null
  }
}
watch(
  () => props.patient,
  newVal => {
    if (Object.keys(newVal).length !== 0) {
      form.value = {
        ...form.value,
        ...newVal,
        idType: String(newVal.idType) || '1',
        gender: String(newVal.gender) || '0',
        maritalStatus: String(newVal.maritalStatus) || '1',
        source: String(newVal.source) || '1',
        occupationType: String(newVal.occupationType) || '1'
      }
    } else {
      resetForm()
    }
  },
  {
    immediate: true,
    deep: true
  }
)
// 姓名、性别校验规则
const validateNameAndSex = (rule, value, callback) => {
  if (!value) {
    callback(new Error('请输入姓名'))
  } else if (!form.value.gender) {
    callback(new Error('请选择性别'))
  } else {
    callback()
  }
}
// 证件类型、证件号码校验规则
const validateIdTypeAndNumber = (rule, value, callback) => {
  // 中文注释：从表单中读取证件类型与号码；优先使用传入的 value 作为待校验号码
  const idType = form.value.idType
  const idNumber = value ?? form.value.idNumber

  // 中文注释：若未选择证件类型，直接提示并返回
  if (!idType) {
    return callback(new Error('请选择证件类型'))
  }

  // 中文注释：号码为空时不做格式校验（是否必填交由其他规则控制）
  if (!idNumber) {
    return callback()
  }

  // 中文注释：分类型校验，避免不同类型共用同一正则导致误判
  if (idType === '1') {
    // 身份证号码正则表达式（不做闰月/大小月细分，仅基础格式）
    const idNumberRegex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
    return idNumberRegex.test(idNumber) ? callback() : callback(new Error('请输入正确的身份证号码'))
  }

  if (idType === '2') {
    // 军官证正则表达式
    const officerIdRegex = /^[A-Za-z0-9]{10}$/
    return officerIdRegex.test(idNumber) ? callback() : callback(new Error('请输入正确的军官证号码'))
  }

  if (idType === '3') {
    // 护照正则表达式
    const passportRegex = /^[A-Za-z0-9]{9,10}$/
    return passportRegex.test(idNumber) ? callback() : callback(new Error('请输入正确的护照号码'))
  }

  // 中文注释：兜底处理，出现未知类型时提示选择证件类型
  return callback(new Error('请选择证件类型'))
}

const rules = ref({
  name: [{ required: true, validator: validateNameAndSex, trigger: 'blur' }],
  phoneNumber: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' }],
  contactName: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
  contactPhone: [
    { required: true, message: '请输入联系电话', trigger: 'blur' },
    { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的联系电话', trigger: 'blur' }
  ],
  contactRelationship: [{ required: true, message: '请选择联系人关系', trigger: 'blur' }],
  // 中文注释：证件类型仅校验是否选择；格式校验在 idNumber 上进行
  idType: [{ required: true, message: '请选择证件类型', trigger: ['change', 'blur'] }],
  // 中文注释：将号码格式校验绑定到 idNumber 字段，保证 value 即为输入的号码
  idNumber: [{ validator: validateIdTypeAndNumber, trigger: ['blur', 'change'] }]
})

// 根据出生日期计算年龄 --岁--月--天
const calculateAge = val => {
  if (val) {
    const birthDate = new Date(val)
    const today = new Date()
    let age = today.getFullYear() - birthDate.getFullYear()
    const month = today.getMonth() - birthDate.getMonth()
    const day = today.getDate() - birthDate.getDate()
    if (month < 0 || (month === 0 && day < 0)) {
      age--
    }
    form.value.age = `${age}岁${month}月${day}天`
  }
}

// 禁用今天之后的日期
const disabledDate = time => {
  return time.getTime() > Date.now()
}
// 暴露表单数据
const exposeForm = () => {
  return new Promise((resolve, reject) => {
    proxy.$refs['hFormRef'].validate((valid, fields) => {
      if (valid) {
        resolve(form.value)
      } else {
        reject(fields)
      }
    })
  })
}

defineExpose({
  exposeForm
})
</script>
<style scoped lang="scss">
@use '@/assets/styles/variables.module.scss' as *;
.grounp-box {
  display: flex;
  align-items: center;
  width: 100%;
  &-name {
    flex: 1;
  }
  &-gender {
    border: solid $border-color;
    border-width: 0 0 0 1px;
    width: 76px;
  }
  &-idType {
    width: 96px;
    border: solid $border-color;
    border-width: 0 1px 0 0;
  }
  &-idNumber {
    flex: 1;
  }
}
</style>
